import { Middleware, MiddlewareContext } from '../../core/types';

export interface RetryOptions {
  retries?: number;
  retryDelay?: number;
  shouldRetry?: (error: any) => boolean;
}

export function retry(options: RetryOptions = {}): Middleware {
  const {
    retries = 3,
    retryDelay = 1000,
    shouldRetry = (err) => !err.response || err.response.status >= 500,
  } = options;

  return async (ctx: MiddlewareContext, next) => {
    let retryCount = 0;
    let lastError: any;

    while (retryCount <= retries) {
      try {
        await next();
        return;
      } catch (error) {
        lastError = error;

        if (!shouldRetry(error)) {
          break;
        }

        retryCount++;
        if (retryCount <= retries) {
          await new Promise((r) => setTimeout(r, retryDelay));
        }
      }
    }

    ctx.error = lastError;
    throw lastError;
  };
}
